#include "pch.h"
#include "Utf8.h"
#include <windows.h>

Utf8::Utf8() {
}

Utf8::Utf8(const Utf8& utf8) {
    this->operator=(utf8);
}


Utf8::Utf8(const std::string& ansiString) {
    std::wstring utf16Str = AnsiToUtf16(ansiString);
    *this = Utf16ToUtf8(utf16Str);
}


Utf8::Utf8(const std::wstring& utf16String) {
    *this = Utf16ToUtf8(utf16String);
}


Utf8::Utf8(const char* memory, int size)
    : std::string(memory, size) {

}

Utf8::Utf8(const std::string& utf8, bool real)
    : std::string(utf8) {
}

Utf8& Utf8::operator=(const std::string& ansiString) {
    std::wstring utf16Str = AnsiToUtf16(ansiString);
    *this = Utf16ToUtf8(utf16Str);
    return *this;
}


Utf8& Utf8::operator=(const std::wstring& utf16String) {
    *this = Utf16ToUtf8(utf16String);
    return *this;
}

Utf8& Utf8::operator=(const Utf8& utf8) {
    this->assign(utf8);
    return *this;
}

std::string Utf8::ToAnsiString() {
    std::wstring utf16 = Utf8ToUtf16(*this);
    return Utf16ToAnsi(utf16);
}

std::wstring Utf8::ToUtf16String() {
    return Utf8ToUtf16(*this);
}

Utf8::~Utf8() {
}

std::wstring Utf8::AnsiToUtf16(const std::string& ansiString) {
    int nCharacters = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, ansiString.c_str(),
                                          ansiString.length(), nullptr, 0);
    std::wstring utf16Str(nCharacters, '\0');
    MultiByteToWideChar(CP_ACP, MB_COMPOSITE, ansiString.c_str(),
                        ansiString.length(), &utf16Str[0], nCharacters);
    return utf16Str;
}

Utf8 Utf8::Utf16ToUtf8(const std::wstring& utf16) {
    int utf8Size = WideCharToMultiByte(CP_UTF8, 0, utf16.c_str(),
                                       utf16.length(), nullptr, 0,
                                       nullptr, nullptr);
    Utf8 utf8Str;
    utf8Str.resize(utf8Size, '\0');
    WideCharToMultiByte(CP_UTF8, 0, utf16.c_str(),
                        utf16.length(), &utf8Str[0], utf8Size,
                        nullptr, nullptr);
    return utf8Str;
}

std::wstring Utf8::Utf8ToUtf16(const Utf8& utf8) {
    std::wstring    utf16;
    int     nCharacters;

    nCharacters = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.length()/*strlen(pszCode) + 1*/, NULL, NULL);
    utf16.resize(nCharacters, L'\0');
    MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.length()/*strlen(pszCode) + 1*/, &utf16[0], nCharacters);
    return utf16;
}

std::string  Utf8::Utf16ToAnsi(const std::wstring& utf16) {
    int bytes = WideCharToMultiByte(CP_ACP, 0, utf16.c_str(), utf16.length(), NULL, 0, NULL, NULL);
    std::string ansiString;
    ansiString.resize(bytes, '\0');
    WideCharToMultiByte(CP_ACP, 0, utf16.c_str(), utf16.length(), &ansiString[0], ansiString.length(), NULL, NULL);
    return ansiString;
}

